package cn.buk.tms.eotms.dao;

import cn.buk.common.sc.CommonSearchCriteria;
import cn.buk.common.sc.Page;
import cn.buk.common.util.DateUtil;
import cn.buk.tms.eotms.entity.TieInProduct;
import cn.buk.tms.eotms.entity.TieInProduct_;
import org.springframework.stereotype.Component;

import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import jakarta.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

/**
 * @author yfdai
 */
@Component
@Transactional
public class ProductDaoImpl extends AbstractDao implements ProductDao {


    @Override
    public int createTieInProduct(TieInProduct p) {
        if (p.getId() > 0) {
          p.setLastUpdate(DateUtil.getCurDateTime());
        }

        if (p.getId() == 0) {
          em.persist(p);
        } else {
          em.merge(p);
        }
        return 1;
    }

    @Override
    public List<TieInProduct> getAllTieInProducts(int enterpriseId) {
        return em.createQuery("select o from TieInProduct o " +
                "where o.enterpriseId = :enterpriseId  order by o.productCode", TieInProduct.class)
                .setParameter("enterpriseId", enterpriseId)
                .getResultList();
    }

    @Override
    public List<TieInProduct> searchTieInProducts(final int ownerId, Integer productType, CommonSearchCriteria sc) {
        List<TieInProduct> results = null;

        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<TieInProduct> cq = cb.createQuery(TieInProduct.class);
        Root<TieInProduct> root = cq.from(TieInProduct.class);
        root.alias("o");

        List<Predicate> predicates = new ArrayList<>();
        Predicate where = cb.conjunction();
        predicates.add(where);

        where = cb.equal(root.get(TieInProduct_.enterpriseId), ownerId);
        predicates.add(where);

        if (sc.getStatus() > -1) {
            where = cb.equal(root.get(TieInProduct_.status), sc.getStatus());
            predicates.add(where);
        }

        if (productType != null) {
            where =cb.equal(root.get(TieInProduct_.productType), productType);
            predicates.add(where);
        }

        //计算根据条件查询得出的数据总数
        CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
        Root<TieInProduct> countRoot = countQuery.from(TieInProduct.class);
        countRoot.alias("o");

        countQuery.select(cb.count(countRoot)).where(predicates.toArray(new Predicate[predicates.size()]));
        Long count = em.createQuery(countQuery).getSingleResult();

        if (count.intValue() > 0) {
            cq.where(predicates.toArray(new Predicate[predicates.size()]));
            List<jakarta.persistence.criteria.Order> orderByes = new ArrayList<>();

            orderByes.add(cb.asc(root.get(TieInProduct_.id)));
            cq.orderBy(orderByes);

            Page page = sc.getPage();
            page.setRowCount(count.intValue());
            int i = (page.getPageNo() - 1) * page.getPageSize();

            if (i < 0) {
                i = 0;
            }

            results = em.createQuery(cq)
                .setFirstResult(i)
                .setMaxResults(page.getPageSize()).getResultList();
        }

        return results == null ? new ArrayList<>() : results;
    }

    @Override
    public int deleteTieInProduct(int enterpriseId, int id) {
        int retCode = 0;
        retCode = em.createQuery("delete from TieInProduct o " +
                "where o.enterpriseId = :enterpriseId  and o.id = :id")
                .setParameter("enterpriseId", enterpriseId)
                .setParameter("id", id)
                .executeUpdate();

        return retCode;
    }

    @Override
    public TieInProduct getTieInProductById(int id) {
        return em.find(TieInProduct.class, id);
    }

    @Override
    public TieInProduct getTieInProductByCode(int enterpriseId, String productCode) {
        List<TieInProduct> list = em.createQuery("select o from TieInProduct o " +
                "where o.enterpriseId = :enterpriseId  and o.productCode = :productCode", TieInProduct.class)
                .setParameter("enterpriseId", enterpriseId)
                .setParameter("productCode", productCode)
                .getResultList();

        return list.size() > 0 ? list.get(0) : null;
    }
}
